package info.batcloud.fanli.core.service.impl;

import info.batcloud.fanli.core.entity.CommissionItem;
import info.batcloud.fanli.core.repository.CommissionItemRepository;
import info.batcloud.fanli.core.service.CommissionItemContentLoader;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import org.apache.commons.io.IOUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Service
public class CommissionItemContentLoaderImpl implements CommissionItemContentLoader {

    private static final Logger logger = LoggerFactory.getLogger(CommissionItemContentLoaderImpl.class);

    @Inject
    private CommissionItemRepository itemRepository;

    @Override
    @Transactional
    public List<String> loadDescImgList(long itemId) {
        CommissionItem item = itemRepository.findOne(itemId);
        if (item.getDescImgList() != null && item.getDescImgList().size() > 0) {
            return item.getDescImgList();
        }
        String content = null;
        switch (item.getEcomPlat()) {
            case TMALL:
            case TAOBAO:
                content = loadTaobaoCommissionItemContent((item.getSourceItemId()));
                break;
            case JD:
                content = loadJdCommissionItemContent(item.getSourceItemId());
                itemRepository.updateDescImgsById(itemId, item.getDescImgs());
                break;
            case PDD:
                List<String> imgs = loadPddCommissionItemContent(item.getSourceItemId());
                item.setDescImgList(imgs);
                itemRepository.updateDescImgsById(itemId, item.getDescImgs());
                return imgs;
            default:
                break;
        }
        Document doc = Jsoup.parse(content);
        List<String> list = new ArrayList<>();
        for (Element img : doc.select("img")) {
            list.add(img.attr("src"));
        }
        item.setDescImgList(list);
        itemRepository.save(item);
        return list;
    }

    private String loadTaobaoCommissionItemContent(long numIid) {
        try {
            String html = IOUtils.toString(new URL("https://item.taobao.com/item.htm?id=" + numIid), "GBK");
            int startIdx = html.indexOf("//desc.alicdn.com");
            int endIdx = html.indexOf(",", startIdx);
            String url = html.substring(startIdx, endIdx - 1);
            String content = IOUtils.toString(new URL("https:" + url), "GBK");
            return content.substring(content.indexOf("'") + 1, content.lastIndexOf("'")).trim();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("抓取淘宝商品详情出错", e);
            return "";
        }

    }

    private String loadJdCommissionItemContent(long skuId) {
        try {
            String html = IOUtils.toString(new URL("https://item.m.jd.com/product/" + skuId + ".html"), "utf8");
            Document document = Jsoup.parse(html);
            for (Element script : document.select("script")) {
                String scriptStr = script.html();
                if (scriptStr.contains("\"description\":\"d")) {
                    ScriptEngineManager m = new ScriptEngineManager();
                    //获取JavaScript执行引擎
                    ScriptEngine engine = m.getEngineByName("JavaScript");
                    //执行JavaScript代码
                    ScriptObjectMirror mirror = (ScriptObjectMirror) engine.eval("var window = {_itemOnly: {}}, _itemOnly = {}; " + scriptStr + "; \n window._itemOnly");
                    String descriptionId = ((ScriptObjectMirror) mirror.get("item")).get("description").toString();
                    String detailUrl = "https://wqsitem.jd.com/detail/" + skuId + "_" + descriptionId + "_plus.html";
                    String descriptionHtml = IOUtils.toString(new URL(detailUrl), "utf8");
                    String descScript = descriptionHtml.substring(descriptionHtml.indexOf("(") + 1, descriptionHtml.lastIndexOf(")"));

                    ScriptObjectMirror descMirror = (ScriptObjectMirror) engine.eval("var x = " + descScript + "\n x");

                    return descMirror.get("content").toString();
                }
            }
            return "";
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("抓取JD商品详情出错", e);
            return "";
        }
    }

    private List<String> loadPddCommissionItemContent(long goodsId) {
        try {
            String html = IOUtils.toString(new URL("https://mobile.yangkeduo.com/goods2.html?goods_id=" + goodsId));
            Document document = Jsoup.parse(html);
            for (Element script : document.select("script")) {
                String scriptStr = script.html();
                if (scriptStr.contains("window.rawData")) {
                    ScriptEngineManager m = new ScriptEngineManager();
                    //获取JavaScript执行引擎
                    ScriptEngine engine = m.getEngineByName("JavaScript");
                    //执行JavaScript代码"initDataObj" -> " size = 33"
                    ScriptObjectMirror mirror = (ScriptObjectMirror) engine.eval("var window = {}; " + scriptStr);
                    ScriptObjectMirror detailGallery = (ScriptObjectMirror) ((ScriptObjectMirror) ((ScriptObjectMirror) ((ScriptObjectMirror)mirror.get("store"))
                            .get("initDataObj"))
                            .get("goods")).get("detailGallery");
                    List<String> srcs = new ArrayList<>();
                    for (String s : detailGallery.keySet()) {
                        ScriptObjectMirror detail = (ScriptObjectMirror) detailGallery.get(s);
                        srcs.add(detail.get("url").toString());
                    }
                    return srcs;
                }
            }
            return new ArrayList<>();
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("抓取PDD商品详情出错", e);
            return new ArrayList<>();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("抓取PDD商品详情出错", e);
            return new ArrayList<>();
        }
    }
}
